#include "SimpleParser.h"
#include <libxml/tree.h>
#include "Gluck.h"

namespace liba {
namespace xml {
namespace parser {

SimpleParser::SimpleParser(void *data, int dataSize)
{
	doc = xmlReadMemory((char*) data, dataSize, NULL, NULL, 0);
	root = xmlDocGetRootElement(doc);
}

SimpleParser::~SimpleParser()
{
	xmlFreeDoc(doc);
}

Node SimpleParser::GetRootNode()
{
	return root;
}

Node SimpleParser::GetNodeByName(Node parentNode, const std::string &name)
{
	if(!parentNode)
		THROW(Gluck(__FUNCTION__, "ParentNode is null for " + name));

	return parentNode.GetNode(name);
}

Nodes SimpleParser::GetNodesByName(Node parentNode, const std::string &name)
{
	if(!parentNode)
		THROW(Gluck(__FUNCTION__, "ParentNode is null for " + name));

	return parentNode.GetNodes(name);
}

std::string SimpleParser::GetAttributeByName(Node node, const std::string &name)
{
	if(!node)
		THROW(Gluck(__FUNCTION__, "Node is null for " + name));

	return node.GetAttribute(name);
}

std::string SimpleParser::GetValue(Node node)
{
	if(!node)
		THROW(Gluck(__FUNCTION__, "Node is null"));

	return node.GetValue();
}




////////////////////////////////////////        /////////////////////////////////////////
///////////////////////////////////////   NODE   ////////////////////////////////////////
////////////////////////////////////////        /////////////////////////////////////////

std::string Node::GetAttribute(const std::string &name) const
{
	xmlAttr *attr = node->properties;
	while(attr)
	{
		if(name == (char*) attr->name)
			return (char*) attr->children->content;

		attr = attr->next;
	}

	return "";
}

std::string Node::GetValue() const
{
	if(!node->children)
		THROW(Gluck(__FUNCTION__, std::string("No data in ") + (char*) node->name));

	return (char*) node->children->content;
}

Node Node::GetNode(const std::string &name) const
{
	xmlNode *nodeIt = node->children;
	while(nodeIt)
	{
		if(name == (char*) nodeIt->name)
			return nodeIt;

		nodeIt = nodeIt->next;
	}

	return NULL;
}

Nodes Node::GetNodes(const std::string &name) const
{
	Nodes nodes;

	xmlNode *nodeIt = node->children;
	while(nodeIt)
	{
		if(nodeIt->type == XML_ELEMENT_NODE && name == (char*)nodeIt->name)
			nodes.push_back(nodeIt);

		nodeIt = nodeIt->next;
	}

	return nodes;
}

}}}